/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package AccesoDatos.Persistencia.Manager;

import AccesoDatos.Persistencia.Entidad.EArea;
import AccesoDatos.Persistencia.Entidad.EAsignado;
import AccesoDatos.Persistencia.Entidad.EAutor;
import AccesoDatos.Persistencia.Entidad.EDescribir;
import AccesoDatos.Persistencia.Entidad.EEditorial;
import AccesoDatos.Persistencia.Entidad.EEjemplar;
import AccesoDatos.Persistencia.Entidad.EEmpleado;
import AccesoDatos.Persistencia.Entidad.EEscrito;
import AccesoDatos.Persistencia.Entidad.ELibro;
import AccesoDatos.Persistencia.Entidad.EOrden;
import AccesoDatos.Persistencia.Entidad.EPedido;
import AccesoDatos.Persistencia.Entidad.EUsuario;
import LogicaNegocio.Biblioteca.Area;
import LogicaNegocio.Biblioteca.Autor;
import LogicaNegocio.Biblioteca.Editorial;
import LogicaNegocio.Biblioteca.Ejemplar;
import LogicaNegocio.Biblioteca.Libro;
import LogicaNegocio.Biblioteca.Orden;
import LogicaNegocio.Biblioteca.PalabraClave;
import LogicaNegocio.Biblioteca.Pedido;
import LogicaNegocio.Empleados.Bibliotecario;
import LogicaNegocio.Usuarios.Usuario;
import MainBiblioSoft.BiblioSoft;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

/**
 * Esta clase en java es el gestor de informes generados
 * a partir de la base de datos BiblioSoft.
 *
 * @author sebaxtian
 * Archivo: ManagerInformes.java
 * @version 1.0
 * Fecha: mar may 11 01:19:30 COT 2010
 */



public class ManagerInformes {

    @PersistenceUnit
    private EntityManagerFactory managerFactory;
    private EntityManager entityManager;
    private ManagerLibro gestorLibro;
    private ManagerEditorial gestorEditorial;
    private ManagerAutor gestorAutor;
    private ManagerArea gestorArea;
    private ManagerEjemplar gestorEjemplar;
    private ManagerPalabra gestorPalabra;
    private ManagerUsuario gestorUsuario;
    private ManagerPedido gestorPedido;

    /**
     * Metodo constructor, crea un gestor de informes
     * para la base de datos BiblioSoft.
     *
     */
    public ManagerInformes() {
        managerFactory = BiblioSoft.managerFactory;
        entityManager = managerFactory.createEntityManager();
        gestorLibro = new ManagerLibro();
        gestorAutor = new ManagerAutor();
        gestorArea = new ManagerArea();
        gestorEjemplar = new ManagerEjemplar();
        gestorPalabra = new ManagerPalabra();
        gestorEditorial = new ManagerEditorial();
        gestorUsuario = new ManagerUsuario();
        gestorPedido = new ManagerPedido();
    }

    /**
     * Este metodo obtiene una lista de las areas de conocimiento
     * que estan registradas en el sistema.
     *
     * @return listaAreas
     */
    public List<Area> obtenerListaAreas() {
        entityManager.clear();
        List<Area> listaAreas = new ArrayList<Area>();
        Area area;
        EArea entidadArea;
        entityManager.clear();
        Query consulta = entityManager.createNamedQuery("EArea.findAll");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadArea = (EArea)iterador.next();
            area = new Area(entidadArea.getCodigoarea(), entidadArea.getCodigoareapadre(), entidadArea.getNombre(), entidadArea.getDescripcion());
            listaAreas.add(area);
        }
        entityManager.clear();
        return listaAreas;
    }

    /**
     * Este metodo obtiene una lista de las editoriales que estan
     * registradas en el sistema
     *
     * @return listaEditoriales
     */
    public List<Editorial> obtenerListaEditoriales() {
        entityManager.clear();
        List<Editorial> listaEditoriales = new ArrayList<Editorial>();
        Editorial editorial;
        EEditorial entidadEditorial;
        entityManager.clear();
        Query consulta = entityManager.createNamedQuery("EEditorial.findAll");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadEditorial = (EEditorial)iterador.next();
            editorial = new Editorial(entidadEditorial.getCodigoeditorial(), entidadEditorial.getNombre(), entidadEditorial.getPaginaweb(), entidadEditorial.getPais());
            listaEditoriales.add(editorial);
        }
        entityManager.clear();
        return listaEditoriales;
    }

    public List<Autor> obtenerListaAutores() {
        entityManager.clear();
        List<Autor> listaAutores = new ArrayList<Autor>();
        Autor autor;
        EAutor entidadAutor;
        Query consulta = entityManager.createNamedQuery("EAutor.findAll");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadAutor = (EAutor)iterador.next();
            autor = new Autor(entidadAutor.getCodigoautor(), entidadAutor.getPrimernombre(), entidadAutor.getPrimerapellido(), entidadAutor.getSegundonombre(), entidadAutor.getSegundoapellido());
            listaAutores.add(autor);
        }
        entityManager.clear();
        return listaAutores;
    }

    /**
     * Obtiene una lista de bibliotecarios obtenida buscandolos por criterios
     * definidos como argumentos.
     * 
     * @param numeroCedula
     * @param primerNombre
     * @param primerApellido
     * @param segundoNombre
     * @param segundoApellido
     * @return listaBibliotecarios
     */
    public List<Bibliotecario> obtenerBibliotecarios(int numeroCedula, String primerNombre, String primerApellido, String segundoNombre, String segundoApellido) {
        entityManager.clear();
        List<Bibliotecario> listaBibliotecarios = new ArrayList<Bibliotecario>();
        Bibliotecario bibliotecario;
        EEmpleado entidadEmpleado;
        Query consulta = entityManager.createQuery("SELECT e FROM EEmpleado e WHERE e.cedulaempleado = :cedulaempleado OR e.primerapellido = :primerapellido OR e.primernombre = :primernombre OR e.segundoapellido = :segundoapellido OR e.segundonombre = :segundonombre");
        consulta.setParameter("cedulaempleado", numeroCedula);
        consulta.setParameter("primernombre", primerNombre);
        consulta.setParameter("primerapellido", primerApellido);
        consulta.setParameter("segundonombre", segundoNombre);
        consulta.setParameter("segundoapellido", segundoApellido);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadEmpleado = (EEmpleado)iterador.next();
            if(entidadEmpleado.getCargo().equals("Bibliotecario")){
                bibliotecario = new Bibliotecario();
                bibliotecario.setCedula(entidadEmpleado.getCedulaempleado());
                bibliotecario.setCedulaEmpleadoJefe(entidadEmpleado.getCedulaempleadojefe());
                bibliotecario.setCargo(entidadEmpleado.getCargo());
                bibliotecario.setDireccion(entidadEmpleado.getDireccion());
                bibliotecario.setPassword(entidadEmpleado.getPassword());
                bibliotecario.setPrimerApellido(entidadEmpleado.getPrimerapellido());
                bibliotecario.setPrimerNombre(entidadEmpleado.getPrimernombre());
                bibliotecario.setSegundoApellido(entidadEmpleado.getSegundoapellido());
                bibliotecario.setSegundoNombre(entidadEmpleado.getSegundonombre());
                bibliotecario.setTelefono(entidadEmpleado.getTelefono());
                bibliotecario.setUniversidad(entidadEmpleado.getUniversidad());
                bibliotecario.setVinculado(entidadEmpleado.getVinculado());
                listaBibliotecarios.add(bibliotecario);
            }
        }
        entityManager.clear();
        return listaBibliotecarios;
    }

    /**
     * Obtiene una lista de autores obtenida buscandolos por criterios
     * definidos como argumentos.
     *
     * @param codigo
     * @param primerNombre
     * @param primerApellido
     * @param segundoNombre
     * @param segundoApellido
     * @return listaAutores
     */
    public List<Autor> obtenerAutores(int codigo, String primerNombre, String primerApellido, String segundoNombre, String segundoApellido) {
        entityManager.clear();
        List<Autor> listaAutores = new ArrayList<Autor>();
        Autor autor;
        EAutor entidadAutor;
        Query consulta = entityManager.createQuery("SELECT e FROM EAutor e WHERE e.codigoautor = :codigoautor OR e.primerapellido = :primerapellido OR e.primernombre = :primernombre OR e.segundoapellido = :segundoapellido OR e.segundonombre = :segundonombre");
        consulta.setParameter("codigoautor", codigo);
        consulta.setParameter("primernombre", primerNombre);
        consulta.setParameter("primerapellido", primerApellido);
        consulta.setParameter("segundonombre", segundoNombre);
        consulta.setParameter("segundoapellido", segundoApellido);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadAutor = (EAutor)iterador.next();
            autor = new Autor();
            autor.setCodigoAutor(entidadAutor.getCodigoautor());
            autor.setPrimerApellido(entidadAutor.getPrimerapellido());
            autor.setPrimerNombre(entidadAutor.getPrimernombre());
            autor.setSegundoApellido(entidadAutor.getSegundoapellido());
            autor.setSegundoNombre(entidadAutor.getSegundonombre());
            listaAutores.add(autor);
        }
        entityManager.clear();
        return listaAutores;
    }

    /**
     * Obtiene una lista de areas obtenidas buscandolas por criterios
     * definidos como argumentos.
     *
     * @param codigo
     * @param nombre
     * @return listaAreas
     */
    public List<Area> obtenerAreas(int codigo, String nombre) {
        entityManager.clear();
        List<Area> listaAreas = new ArrayList<Area>();
        Area area;
        EArea entidadArea;
        Query consulta = entityManager.createQuery("SELECT e FROM EArea e WHERE e.codigoarea = :codigoarea OR e.nombre LIKE :nombre");
        consulta.setParameter("codigoarea", codigo);
        consulta.setParameter("nombre", "%"+nombre+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadArea = (EArea)iterador.next();
            area = new Area();
            area.setCodigoArea(entidadArea.getCodigoarea());
            area.setNombre(entidadArea.getNombre());
            listaAreas.add(area);
        }
        entityManager.clear();
        return listaAreas;
    }

    /**
     * Obtiene una lista de editoriales obtenidas buscandolas por criterios
     * definidos como argumentos.
     *
     * @param nombre
     * @return listaEditoriales
     */
    public List<Editorial> obtenerEditoriales(String nombre) {
        entityManager.clear();
        List<Editorial> listaEditoriales = new ArrayList<Editorial>();
        Editorial editorial;
        EEditorial entidadEditorial;
        Query consulta = entityManager.createQuery("SELECT e FROM EEditorial e WHERE e.nombre LIKE :nombre");
        consulta.setParameter("nombre", "%"+nombre+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadEditorial = (EEditorial)iterador.next();
            editorial = new Editorial();
            editorial.setCodigoEditorial(entidadEditorial.getCodigoeditorial());
            editorial.setNombre(entidadEditorial.getNombre());
            editorial.setPaginaWeb(entidadEditorial.getPaginaweb());
            editorial.setPais(entidadEditorial.getPais());
            listaEditoriales.add(editorial);
        }
        entityManager.clear();
        return listaEditoriales;
    }

    /**
     * Busca si existe un ejemplar en la biblioteca con la misma referencia
     * definida como argumentos.
     *
     * @param numeroSala
     * @param numeroPasillo
     * @param numeroEstante
     * @param numeroCajon
     * @return existe
     */
    public boolean existeEjemplar(int numeroSala, int numeroPasillo, int numeroEstante, int numeroCajon) {
        entityManager.clear();
        boolean existe = false;
        Query consulta = entityManager.createQuery("SELECT e FROM EEjemplar e WHERE e.numerosala = :numerosala AND e.numeropasillo = :numeropasillo AND e.numeroestante = :numeroestante AND e.numerocajon = :numerocajon");
        consulta.setParameter("numerosala", numeroSala);
        consulta.setParameter("numeropasillo", numeroPasillo);
        consulta.setParameter("numeroestante", numeroEstante);
        consulta.setParameter("numerocajon", numeroCajon);
        if(!consulta.getResultList().isEmpty()){
            existe = true;
        }
        entityManager.clear();
        return existe;
    }

    /**
     * Obtiene un ejemplar buscandolo con la referencia que recibe como
     * atributos. retorna null si no existe.
     *
     * @param numeroSala
     * @param numeroPasillo
     * @param numeroEstante
     * @param numeroCajon
     * @return ejemplar
     */
    public Ejemplar obtenerEjemplar(int numeroSala, int numeroPasillo, int numeroEstante, int numeroCajon) {
        entityManager.clear();
        Ejemplar ejemplar = null;
        EEjemplar entidadEjemplar;
        Query consulta = entityManager.createQuery("SELECT e FROM EEjemplar e WHERE e.numerosala = :numerosala AND e.numeropasillo = :numeropasillo AND e.numeroestante = :numeroestante AND e.numerocajon = :numerocajon");
        consulta.setParameter("numerosala", numeroSala);
        consulta.setParameter("numeropasillo", numeroPasillo);
        consulta.setParameter("numeroestante", numeroEstante);
        consulta.setParameter("numerocajon", numeroCajon);
        if(existeEjemplar(numeroSala, numeroPasillo, numeroEstante, numeroCajon)){
            entidadEjemplar = (EEjemplar)consulta.getResultList().get(0);
            ejemplar = new Ejemplar();
            ejemplar.setDisponible(entidadEjemplar.getDisponible());
            ejemplar.setIdEjemplar(entidadEjemplar.getIdejemplar());
            ejemplar.setIsbn(entidadEjemplar.getIsbn());
            ejemplar.setNumeroCajon(entidadEjemplar.getNumerocajon());
            ejemplar.setNumeroEstante(entidadEjemplar.getNumeroestante());
            ejemplar.setNumeroPasillo(entidadEjemplar.getNumeropasillo());
            ejemplar.setNumeroSala(entidadEjemplar.getNumerosala());
        }
        entityManager.clear();
        return ejemplar;
    }

    /**
     * Actualiza el campo numero de busquedas
     * incrementandolo en una unidad.
     *
     * @param libro
     * @return libro
     */
    private void libroEncontrado(Libro libro) {
        if(libro != null){
            libro.setCantidadBusquedas(libro.getCantidadBusquedas()+1);
            gestorLibro.actualizarLibro(libro.getIsbn(), libro);
        }
    }

    /**
     * Busca libros por un criterio de busqueda, una busqueda se realiza con cualquier
     * criterio definido como argumento.
     *
     * @param isbn
     * @param titulo
     * @param primerNombreAutor
     * @param segundoNombreAutor
     * @param primerApellidoAutor
     * @param segundoApellidoAutor
     * @param palabraClave
     * @param editorial
     * @param areaConocimiento
     * @param anoPulicacion
     * @param idioma
     * @return listaLibrosEncontrados
     */
    public List<Libro> buscarLibro(Long isbn, String titulo, String primerNombreAutor, String segundoNombreAutor, String primerApellidoAutor, String segundoApellidoAutor, String palabraClave, String editorial, String areaConocimiento, int anoPulicacion, String idioma) {
        List<Libro> listaLibrosEncontrados = new ArrayList<Libro>();
        Libro libro = gestorLibro.obtenerLibro(isbn);
        if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
            libroEncontrado(libro);
            libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
            libro.setListaAreas(obtenerListaAreas(libro));
            libro.setListaAutores(obtenerListaAutores(libro));
            libro.setListaEjemplares(obtenerListaEjemplares(libro));
            libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
            listaLibrosEncontrados.add(libro);
        }
        listaLibrosEncontrados = buscarLibroAnoPublicacion(anoPulicacion, listaLibrosEncontrados);
        listaLibrosEncontrados = buscarLibroAreaConocimiento(areaConocimiento, listaLibrosEncontrados);
        listaLibrosEncontrados = buscarLibroAutor(primerNombreAutor, segundoNombreAutor, primerApellidoAutor, segundoApellidoAutor, listaLibrosEncontrados);
        listaLibrosEncontrados = buscarLibroEditorial(editorial, listaLibrosEncontrados);
        listaLibrosEncontrados = buscarLibroIdioma(idioma, listaLibrosEncontrados);
        listaLibrosEncontrados = buscarLibroPalabraClave(palabraClave, listaLibrosEncontrados);
        listaLibrosEncontrados = buscarLibroTitulo(titulo, listaLibrosEncontrados);
        return listaLibrosEncontrados;
    }

    /**
     * Busca libros por un criterio de busqueda que es el titulo del libro
     *
     * @param titulo
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroTitulo(String titulo, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        ELibro entidadLibro;//SELECT ISBN FROM LIBRO WHERE TITULO LIKE "%MARISOL%"
        Query consulta = entityManager.createQuery("SELECT e FROM ELibro e WHERE e.titulo LIKE :titulo");
        consulta.setParameter("titulo", "%"+titulo+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadLibro = (ELibro)iterador.next();
            libro = gestorLibro.obtenerLibro(entidadLibro.getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Busca libros por criterio de busqueda que es el nombre del autor.
     *
     * @param primerNombreAutor
     * @param segundoNombreAutor
     * @param primerApellidoAutor
     * @param segundoApellidoAutor
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroAutor(String primerNombreAutor, String segundoNombreAutor, String primerApellidoAutor, String segundoApellidoAutor, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        EEscrito entidadEscrito;//SELECT ISBN FROM ESCRITO WHERE CODIGOAUTOR IN (SELECT CODIGOAUTOR FROM AUTOR WHERE SEGUNDONOMBRE LIKE "%ANDREA%")
        //SELECT e FROM EEscrito e WHERE e.eEscritoPK.codigoautor = :codigoautorDISTINCT
        Query consulta = entityManager.createQuery("SELECT e FROM EEscrito e WHERE e.eEscritoPK.codigoautor IN (SELECT a.codigoautor FROM EAutor a WHERE a.primerapellido LIKE :primerapellido OR a.segundoapellido LIKE :segundoapellido OR a.primernombre LIKE :primernombre OR a.segundonombre LIKE :segundonombre)");
        consulta.setParameter("primerapellido", "%"+primerApellidoAutor+"%");
        consulta.setParameter("segundoapellido", "%"+segundoApellidoAutor+"%");
        consulta.setParameter("primernombre", "%"+primerNombreAutor+"%");
        consulta.setParameter("segundonombre", "%"+segundoNombreAutor+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadEscrito = (EEscrito)iterador.next();
            libro = gestorLibro.obtenerLibro(entidadEscrito.getEEscritoPK().getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Busca libros por criterio de busqueda que es el nombre de la palabra clave.
     *
     * @param palabraClave
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroPalabraClave(String palabraClave, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        EDescribir entidadDescribir;//SELECT ISBN FROM DESCRIBIR WHERE IDPALABRA IN (SELECT IDPALABRA FROM PALABRA WHERE NOMBRE = "algebra")
        Query consulta = entityManager.createQuery("SELECT e FROM EDescribir e WHERE e.eDescribirPK.idpalabra IN (SELECT a.idpalabra FROM EPalabra a WHERE a.nombre = :nombre)");
        consulta.setParameter("nombre", palabraClave);
        Iterator iterator = consulta.getResultList().iterator();
        while(iterator.hasNext()){
            entidadDescribir = (EDescribir)iterator.next();
            libro = gestorLibro.obtenerLibro(entidadDescribir.getEDescribirPK().getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Busca libros por criterio de busqueda que es el nombre de la editorial.
     *
     * @param editorial
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroEditorial(String editorial, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        ELibro entidadLibro;//SELECT ISBN FROM LIBRO WHERE CODIGOEDITORIAL IN (SELECT CODIGOEDITORIAL FROM EDITORIAL WHERE NOMBRE = "mcgrawhill")
        Query consulta = entityManager.createQuery("SELECT e FROM ELibro e WHERE e.codigoeditorial IN (SELECT a.codigoeditorial FROM EEditorial a WHERE a.nombre LIKE :nombre)");
        consulta.setParameter("nombre", "%"+editorial+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()) {
            entidadLibro = (ELibro)iterador.next();
            libro = gestorLibro.obtenerLibro(entidadLibro.getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Buscar libros por criterio de busqueda que es el nombre del area de conocimiento.
     *
     * @param areaConocimiento
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroAreaConocimiento(String areaConocimiento, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        EAsignado entidadAsignado;//SELECT ISBN FROM ASIGNADO WHERE CODIGOAREA IN (SELECT CODIGOAREA FROM AREA WHERE LIKE "%algebra%")
        Query consulta = entityManager.createQuery("SELECT e FROM EAsignado e WHERE e.eAsignadoPK.codigoarea IN (SELECT a.codigoarea FROM EArea a WHERE a.nombre LIKE :nombre)");
        consulta.setParameter("nombre", "%"+areaConocimiento+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadAsignado = (EAsignado)iterador.next();
            libro = gestorLibro.obtenerLibro(entidadAsignado.getEAsignadoPK().getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Busca libros por criterio de busqueda que es el ano de la publicacion.
     *
     * @param anoPublicacion
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroAnoPublicacion(int anoPublicacion, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        String ano = anoPublicacion+"";
        ELibro entidadLibro;//SELECT ISBN FROM LIBRO WHERE YEAR(ANOPUBLICACION) = 1999
        Query consulta = entityManager.createQuery("SELECT e FROM ELibro e WHERE CONCAT(e.anopublicacion,'') LIKE :anopublicacion");
        consulta.setParameter("anopublicacion", "%"+anoPublicacion+"%");
//        consulta.setParameter("anopublicacion2", fecha.getTime());
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadLibro = (ELibro)iterador.next();
            System.out.println(""+entidadLibro.getAnopublicacion());
            libro = gestorLibro.obtenerLibro(entidadLibro.getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Busca libros por criterio de busqueda que es el idioma.
     *
     * @param idioma
     * @param listaLibrosEncontrados
     * @return listaLibrosEncontrados
     */
    private List<Libro> buscarLibroIdioma(String idioma, List<Libro> listaLibrosEncontrados) {
        entityManager.clear();
        Libro libro;
        ELibro entidadLibro;//SELECT ISBN FROM LIBRO WHERE idioma = "español"
        Query consulta = entityManager.createQuery("SELECT e FROM ELibro e WHERE e.idioma LIKE :idioma");
        consulta.setParameter("idioma", "%"+idioma+"%");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadLibro = (ELibro)iterador.next();
            libro = gestorLibro.obtenerLibro(entidadLibro.getIsbn());
            if(libro != null && !contieneLibro(libro, listaLibrosEncontrados)){
                libroEncontrado(libro);
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosEncontrados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosEncontrados;
    }

    /**
     * Obtiene la lista de autores de un libro.
     *
     * @param libro
     * @return listaAutores
     */
    private List<Autor> obtenerListaAutores(Libro libro) {
        entityManager.clear();
        List<Autor> listaAutores = new ArrayList<Autor>();
        Autor autor;
        EEscrito entidadEscrito;
        Query consulta = entityManager.createQuery("SELECT e FROM EEscrito e WHERE e.eEscritoPK.isbn = :isbn");
        consulta.setParameter("isbn", libro.getIsbn());
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadEscrito = (EEscrito)iterador.next();
            autor = gestorAutor.obtenerAutor(entidadEscrito.getEEscritoPK().getCodigoautor());
            if(autor != null)
            listaAutores.add(autor);
        }
        entityManager.clear();
        return listaAutores;
    }

    /**
     * Obtiene la lista de areas de conocimiento de un libro.
     *
     * @param libro
     * @return listaAreas
     */
    private List<Area> obtenerListaAreas(Libro libro) {
        entityManager.clear();
        List<Area> listaAreas = new ArrayList<Area>();
        Area area;
        EAsignado entidadAsigando;
        Query consulta = entityManager.createQuery("SELECT e FROM EAsignado e WHERE e.eAsignadoPK.isbn = :isbn");
        consulta.setParameter("isbn", libro.getIsbn());
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadAsigando = (EAsignado)iterador.next();
            area = gestorArea.obtenerArea(entidadAsigando.getEAsignadoPK().getCodigoarea());
            if(area != null)
            listaAreas.add(area);
        }
        entityManager.clear();
        return listaAreas;
    }

    /**
     * Obtiene la lista de ejemplares de un libro.
     *
     * @param libro
     * @return listaEjemplares
     */
    private List<Ejemplar> obtenerListaEjemplares(Libro libro) {
        entityManager.clear();
        List<Ejemplar> listaEjemplares = new ArrayList<Ejemplar>();
        Ejemplar ejemplar;
        EEjemplar entidadEjemplar;
        Query consulta = entityManager.createQuery("SELECT e FROM EEjemplar e WHERE e.isbn = :isbn");
        consulta.setParameter("isbn", libro.getIsbn());
        Iterator iterator = consulta.getResultList().iterator();
        while(iterator.hasNext()){
            entidadEjemplar = (EEjemplar)iterator.next();
            ejemplar = gestorEjemplar.obtenerEjemplar(entidadEjemplar.getIdejemplar());
            if(ejemplar != null)
            listaEjemplares.add(ejemplar);
        }
        entityManager.clear();
        return listaEjemplares;
    }

    /**
     * Obtiene la lista de palabras clave que describen un libro.
     *
     * @param libro
     * @return listaPalabrasClave
     */
    private List<PalabraClave> obtenerListaPalabrasClave(Libro libro) {
        entityManager.clear();
        List<PalabraClave> listaPalabrasClave = new ArrayList<PalabraClave>();
        PalabraClave palabra;
        EDescribir entidadDescribir;
        Query consulta = entityManager.createQuery("SELECT e FROM EDescribir e WHERE e.eDescribirPK.isbn = :isbn");
        consulta.setParameter("isbn", libro.getIsbn());
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadDescribir = (EDescribir)iterador.next();
            palabra = gestorPalabra.obtenerPalabra(entidadDescribir.getEDescribirPK().getIdpalabra());
            if(palabra != null)
            listaPalabrasClave.add(palabra);
        }
        entityManager.clear();
        return listaPalabrasClave;
    }

    /**
     * Busca en la lista de libros si ya contiene el libro
     * que recibe como argumento.
     *
     * @param libro
     * @param listaLibros
     * @return contiene
     */
    private boolean contieneLibro(Libro libro, List<Libro> listaLibros) {
        boolean contiene = false;
        for (Libro libro1 : listaLibros) {
            if(libro.getIsbn().equals(libro1.getIsbn())){
                contiene = true;
                break;
            }
        }
        return contiene;
    }

    public List<Orden> obtenerOrdenesDelDia() {
        entityManager.clear();
        List<Orden> listaOrdenes = new ArrayList<Orden>();
        Orden orden = null;
        Date fecha = Calendar.getInstance().getTime();
        EOrden entidadOrden;//SELECT * FROM ORDEN WHERE FECHAORDEN = '2010-06-03' AND CANCELADA = FALSE;
        Query consulta = entityManager.createQuery("SELECT e FROM EOrden e WHERE e.fechaorden = :fechaorden AND e.cancelada = FALSE");
        consulta.setParameter("fechaorden", fecha);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadOrden = (EOrden)iterador.next();
            orden = new Orden();
            orden.setCancelada(entidadOrden.getCancelada());
            orden.setEjemplar(gestorEjemplar.obtenerEjemplar(entidadOrden.getIdejemplar()));
            orden.setFecha(entidadOrden.getFechaorden());
            orden.setHora(entidadOrden.getHoraorden());
            orden.setIdEjemplar(entidadOrden.getIdejemplar());
            orden.setIdOrden(entidadOrden.getIdorden());
            orden.setIdentificacionUsuario(entidadOrden.getIdentificacionusuario());
            try {
                orden.setUsuario(gestorUsuario.obtenerUsuario(entidadOrden.getIdentificacionusuario()));
            } catch (Exception ex) {
            }
            listaOrdenes.add(orden);
        }
        entityManager.clear();
        return listaOrdenes;
    }

    public List<Ejemplar> obtenerEjemplaresPrestadosA(int identificacionUsuario) {
        entityManager.clear();
        List<Ejemplar> listaEjemplares = new ArrayList<Ejemplar>();
        Ejemplar ejemplar;
        int idEjemplar = -1;
        /*
         * SELECT DISTINCT ORDEN.IDEJEMPLAR FROM ORDEN,PRESTAMO WHERE ORDEN.IDENTIFICACIONUSUARIO = 1143825130 AND ORDEN.IDORDEN = PRESTAMO.IDORDEN AND PRESTAMO.DEVUELTO = FALSE;
        */
        Query consulta = entityManager.createQuery("SELECT DISTINCT o.idejemplar FROM EOrden o, EPrestamo p WHERE o.identificacionusuario = :identificacionusuario AND o.idorden = p.idorden AND p.devuelto = FALSE");
        consulta.setParameter("identificacionusuario", identificacionUsuario);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            idEjemplar = (Integer)iterador.next();
            ejemplar = gestorEjemplar.obtenerEjemplar(idEjemplar);
            listaEjemplares.add(ejemplar);
        }
        entityManager.clear();
        return listaEjemplares;
    }

    public int obtenerValorMulta(int identificacionUsuario) {
        entityManager.clear();
        int valorMulta = 0;
        Query consulta = entityManager.createQuery("SELECT SUM(e.valor) FROM EMulta e WHERE e.identificacionusuario = :identificacionusuario AND e.cancelada = FALSE");
        consulta.setParameter("identificacionusuario", identificacionUsuario);
        if(consulta.getSingleResult() != null){
            valorMulta = new Integer(consulta.getSingleResult().toString());
        }
        entityManager.clear();
        return valorMulta;
    }

    public boolean ejemplarVencido(int idEjemplar){
        entityManager.clear();
        boolean vencido = false;
        Date fechaActual = Calendar.getInstance().getTime();
        Date fechaEntrega;
        /*
         * SELECT DISTINCT FECHAENTREGA FROM PRESTAMO,ORDEN WHERE ORDEN.IDEJEMPLAR = 2 AND PRESTAMO.IDORDEN = ORDEN.IDORDEN AND PRESTAMO.DEVUELTO = FALSE;
         */
        Query consulta = entityManager.createQuery("SELECT DISTINCT p.fechaentrega FROM EPrestamo p, EOrden o WHERE o.idejemplar = :idejemplar AND p.idorden = o.idorden AND p.devuelto = FALSE");
        consulta.setParameter("idejemplar", idEjemplar);
        fechaEntrega = (Date)consulta.getSingleResult();
        vencido = fechaEntrega.before(fechaActual);
        entityManager.clear();
        return vencido;
    }

    public List<Usuario> obtenerUsuariosDeudores() {
        entityManager.clear();
        List<Usuario> listaUsuariosDeudores = new ArrayList<Usuario>();
        Usuario usuario;
        EUsuario entidadUsuario;
        /**
         * SELECT * FROM USUARIO U WHERE (SELECT SUM(M.VALOR) FROM MULTA M WHERE M.IDENTIFICACIONUSUARIO = U.IDENTIFICACIONUSUARIO AND M.CANCELADA = FALSE) > 0;
         */
        Query consulta = entityManager.createQuery("SELECT u FROM EUsuario u WHERE (SELECT SUM(m.valor) FROM EMulta m WHERE m.identificacionusuario = u.identificacionusuario AND m.cancelada = FALSE) > 0");
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadUsuario = (EUsuario)iterador.next();
            usuario = new Usuario();
            usuario.setActivo(entidadUsuario.getActivo());
            usuario.setDireccion(entidadUsuario.getDireccion());
            usuario.setEmail(entidadUsuario.getEmail());
            usuario.setIdentificacionUsuario(entidadUsuario.getIdentificacionusuario());
            usuario.setPrimerApellido(entidadUsuario.getPrimerapellido());
            usuario.setPrimerNombre(entidadUsuario.getPrimernombre());
            usuario.setSegundoApellido(entidadUsuario.getSegundoapellido());
            usuario.setSegundoNombre(entidadUsuario.getSegundonombre());
            usuario.setTelefono(entidadUsuario.getTelefono());
            usuario.setValorDeuda(obtenerValorMulta(entidadUsuario.getIdentificacionusuario()));
            listaUsuariosDeudores.add(usuario);
        }
        entityManager.clear();
        return listaUsuariosDeudores;
    }

    public List<Pedido> obtenerLibrosPorComprar() {
        entityManager.clear();
        List<Pedido> listaLibrosPorComprar = new ArrayList<Pedido>();
        Pedido pedido;
        EPedido entidadPedido;
        Query consulta = entityManager.createNamedQuery("EPedido.findByComprado");
        consulta.setParameter("comprado", false);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadPedido = (EPedido)iterador.next();
            pedido = gestorPedido.obtenerPedido(entidadPedido.getNumeropedido());
            listaLibrosPorComprar.add(pedido);
        }
        entityManager.clear();
        return listaLibrosPorComprar;
    }

    public List<Libro> obtenerLibrosPorArea(String nombreArea) {
        List<Libro> listaLibros = new ArrayList<Libro>();
        listaLibros = buscarLibroAreaConocimiento(nombreArea, listaLibros);
        return listaLibros;
    }

    public List<Libro> obtenerLibrosPrestadosPorArea(String nombreArea) {
        //SELECT DISTINCT E.ISBN FROM EJEMPLAR E, ORDEN O, PRESTAMO P, AREA A WHERE E.IDEJEMPLAR = O.IDEJEMPLAR AND P.IDORDEN = O.IDORDEN AND P.DEVUELTO = FALSE AND A.NOMBRE = "algebra LINEAL";
        entityManager.clear();
        List<Libro> listaLibrosPrestadosPorArea = new ArrayList<Libro>();
        Libro libro;
        Query consulta = entityManager.createQuery("SELECT DISTINCT e.isbn FROM EEjemplar e, EOrden o, EPrestamo p, EArea a WHERE e.idejemplar = o.idejemplar AND p.idorden = o.idorden AND p.devuelto = FALSE AND a.nombre = :nombre");
        consulta.setParameter("nombre", nombreArea);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            Long ISBN = (Long)iterador.next();
            libro = gestorLibro.obtenerLibro(ISBN);
            if(libro != null){
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosPrestadosPorArea.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosPrestadosPorArea;
    }

    public List<Libro> obtenerLibrosMasBuscados() {
        entityManager.clear();
        List<Libro> listaLibrosMasBuscados = new ArrayList<Libro>();
        int promedioBusquedas = obtenerPromedioBusquedas();
        ELibro entidadLibro;
        Libro libro;
        Query consulta = entityManager.createQuery("SELECT e FROM ELibro e WHERE e.cantbusquedas > :cantbusquedas");
        consulta.setParameter("cantbusquedas", promedioBusquedas);
        Iterator iterador = consulta.getResultList().iterator();
        while(iterador.hasNext()){
            entidadLibro = (ELibro)iterador.next();
            libro = gestorLibro.obtenerLibro(entidadLibro.getIsbn());
            if(libro != null){
                libro.setEditorial(gestorEditorial.obtenerEditorial(libro.getCodigoEditorial()));
                libro.setListaAreas(obtenerListaAreas(libro));
                libro.setListaAutores(obtenerListaAutores(libro));
                libro.setListaEjemplares(obtenerListaEjemplares(libro));
                libro.setListaPalabrasClave(obtenerListaPalabrasClave(libro));
                listaLibrosMasBuscados.add(libro);
            }
        }
        entityManager.clear();
        return listaLibrosMasBuscados;
    }

    private int obtenerPromedioBusquedas() {
        entityManager.clear();
        double avg = 0;
        int promedio = 0;
        //SELECT AVG(CANTBUSQUEDAS) FROM LIBRO WHERE ACTIVO = TRUE;
        Query consulta = entityManager.createQuery("SELECT AVG(e.cantbusquedas) FROM ELibro e WHERE e.activo = TRUE");
        if(consulta.getSingleResult() != null){
            avg = (Double)consulta.getSingleResult();
            promedio = (int)avg;
        }
        entityManager.clear();
        return promedio;
    }
}

